#Delete the output of this cell
%%capture
# Install python biblio
!pip install -U -q PyDrive
!pip install plotly
!pip install cufflinks
!pip intasl colorlover
!pip install lightgbm
!pip install xgboost
!pip install lime
!pip install optuna
!pip install forestci
!pip install missingno
!pip install ipywidgets
!pip install qgrid
!pip install https://github.com/ipython-contrib/jupyter_contrib_nbextensions/tarball/master
!jupyter contrib nbextension install --user
!jupyter nbextension enable hinterland/hinterland
# Install Linux Libraries
!apt-get install unrar
!apt-get install unzip
# numpy and pandas for data manipulation
import io
import os
import pandas as pd
import numpy as np
import warnings
import datetime
from datetime import timedelta
# Authentification
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from google.colab import auth
from oauth2client.client import GoogleCredentials
from google.colab import auth
from googleapiclient.discovery import build
from googleapiclient.http import MediaIoBaseDownload
import google.colab
import glob
# matplotlib, plotly and seaborn for plotting
import plotly.offline as py
from plotly.offline import init_notebook_mode, iplot
from plotly.graph_objs import Contours, Histogram2dContour, Marker, Scatter
import plotly.graph_objs as go
from plotly import tools
import plotly.figure_factory as ff
import qgrid
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib
# sklearn preprocessing for dealing with categorical variables
from sklearn.preprocessing import LabelEncoder
##from sklearn import preprocessing
import cufflinks as cf
from collections import Counter
#libraries for the model
from sklearn.metrics import accuracy_score
from sklearn.model_selection import KFold
from sklearn.metrics import roc_auc_score
from sklearn.preprocessing import MinMaxScaler
from sklearn.neural_network import MLPClassifier
from xgboost import XGBClassifier
#from sklearn.impute import SimpleImputer
from sklearn import metrics
import lightgbm as lgb
import gc
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.ensemble import RandomForestRegressor
from sklearn.datasets import make_classification
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from scipy.stats import normaltest
from scipy import stats
import lime
import lime.lime_tabular
#Some Libraries configurations
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:100% !important; }</style>")) # Para expandir o output do dataframe para 100%
#Import sklearn's feature selection algorithm
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
from sklearn.feature_selection import SelectFromModel
#import featuretools as ft #back to work again
import missingno as msno
#Use the plotly API in google colab
def configure_plotly_browser_state():
import IPython
display(IPython.core.display.HTML('''
<script src="/static/components/requirejs/require.js"></script>
<script>
requirejs.config({
paths: {
base: '/static/base',
plotly: 'https://cdn.plot.ly/plotly-1.5.1.min.js?noext',
},
});
</script>
'''))
#dataframe: the dictionary that you want to remove de missing columns
#limit: the percentage of missings that its allouwed
#axis 0 for index 1 to column
def remove_missing(dataframe, limit, axis):
if axis == 1:
dataframe = dataframe.dropna(thresh=(1-limit)*df.shape[0], axis=axis, inplace=True)
else:
dataframe = dataframe.dropna(thresh=(1-limit)*df.shape[1], axis=axis, inplace=True)
def dummycount(dataframe):
sum = 0
for col in dataframe.select_dtypes(include=['object']).columns:
unique = len(dataframe[col].unique())
sum+= unique
print('Quantidade de valores unicos da coluna: ',col,' : ',unique)
print('A quantidade de colunas que sera gerada pelo get_dummies() e:', sum)
# #avaliar o contrario
# import pandas as pd
# df = pd.DataFrame({'cat':['a','b','c','d'],'val':[1,2,5,10]})
# df1 = pd.get_dummies(pd.DataFrame({'cat':['a'],'val':[1]}))
# dummies_frame = pd.get_dummies(df)
# df1.reindex(columns = dummies_frame.columns, fill_value=0)
train = pd.read_csv('/content/drive/MyDrive/CALPM_DATASET/train.csv', sep = ';', encoding='UTF-8')
test = pd.read_csv('/content/drive/MyDrive/CALPM_DATASET/test.csv', sep = ';', encoding='UTF-8')
train.head(3)
#Distribuicao da variavel target
configure_plotly_browser_state()
init_notebook_mode(connected=False)
data1 = [{'labels': ['0 - Inactive', '1 - Active'],
'values': [train.ind_atividade.value_counts()[0], train.ind_atividade.value_counts()[1]],
'type': 'pie'}]
iplot(data1)
# quarentena_sms['dataEnvio']= pd.to_datetime(quarentena_sms['dataEnvio'], format='%d/%m/%Y %H:%M:%S')
# quarentena_campanhas['TMPCAM'] = ((datetime.datetime.now() - quarentena_campanhas['DATENV']).dt.days)
df = train.copy()
df.shape
df.dtypes
Como podemos observar temos variaveis do tipo int, float, bool e object(string).
O prƩfixo do nome das variaveis traz mais detalhes sobre o tipo de dados.
fl = flag = bool(True,False)
vl, qt, cd = valor, quantidade, codigo = numeric(int,float)
nm, de, sg = nome, descricacao, sigla = object(string)
dt, dh = data, datahora = object(date,datetime)
id = identificador = numeric(int)
ind_atividade = target = numeric(int)
#Função que substitui '' por NaN
df.replace('',np.nan, inplace=True)
df.columns[df.isnull().any()].tolist()
#Função que a apresenta as colunas que possuem pelo menos 1 valor faltando
len(df.columns[df.isnull().any()].tolist())
Como pode ser observado das 74 colunas do dataset 35 apresentam pelo menos 1 valor faltando.
#Caso exister alguma coluna e seja necessÔrio ver a contagem de valores faltando por coluna use o código abaixo
df.info(verbose=True, null_counts=True)
Como pode ser observado dentre as colunas com valores faltando existem aglumas com mais de 30% de seus valores faltando. Essas colunas serao removidas na proxima etapa.
Para remover as colunas com mais de 30% de valores faltando sera aplicada a função remove_missing.
remove_missing(df, 0.30,1)
A seguir sera verificado se ainda existem colunas com valores faltando e quais sao elas.
df.columns[df.isnull().any()].tolist()
A seguir sao analisados quantas linhas possuem valor faltando nessas 4 colunas.
len(df[df.isna().any(axis=1)])
Como essa quantidade de linhas corresponde a 2% do total no primeiro momento elas serao excluidas. Apos identificar se essas colunas possuem poder preditivo, uma estrategia de substituicao de valores faltando podera ser adotada.
round(len(df[df.isna().any(axis=1)])/len(df),2)
Para remover essas linhas sera utilizada novamente a funcacao remove_missing passan o parametro axis = 0 para indicar que as linhas devem ser removidas.
remove_missing(df, 0,0)
len(df[df.isna().any(axis=1)])
Como pode ser observado, não sobrou nenhuma linha com valores faltando.
Nesta etapa o dataset sera preparado para os algoritmos de aprendizado de maquina. Dentre as operações realizadas nessa estapa estao: Conversão de Tipos, Encoding e Engenharia de caracteristicas.
df.head(3)
Como podemos observar as variaveis flag possuem valores(True, False). Para serem utilizados no algoritmo esses valores serao convertidos em (1,0).
df.update(df.filter(regex='^fl_').astype(int))
df.head(3)
O proximo passo seria corrigir as colunas do com prefixo dt e dh para serem reconhecidas como tipo datetime. PorĆ©m como esse nĆ£o Ć© um modelo de serie temporal, e como nĆ£o serĆ” necessĆ”rio fazer ordenaƧƵes por data essas colunas serĆ£o utilizadas para gerar novas variaveis na etapa de engenharia de caracterĆsticas.
A seguir as variaveis dt_abertura e dh_processamento são utilizadas para gerar o tempo de abertura da empresa em anos.
df['ano_abertura']=df['dt_abertura'].str.split('-').str[0]
df['ano_processamento']=df['dh_processamento'].str.split('-').str[0]
df['tempo_empresa']= df['ano_processamento'].astype(int) - df['ano_abertura'].astype(int)
df.head(3)
Como podemos observar o dataset agora possuà a variavel tempo_empresa que representa o tempo de abertura da empresa em anos no momento do processamento da base. Essa variravel ajudarÔ a testa a hipótese de que a maior parte das empresas acapa falindo e deixando de operar nos primeiros anos de abertura.
df.dtypes
Como as variaveis do tipo data não serão utilizados elas serão removidas do dataset.
df.drop(['ano_abertura','ano_processamento','dt_abertura', 'dt_situacao','dh_ultima_atualizacao', 'dh_processamento'],axis=1, inplace=True)
A seguir as variaveis categoricas serão transformada em variaveis dummy, onde cada categoria irÔ se tornar uma nova coluna no dataset. Antes de fazer a transformação serão avaliadas as quantidade de categorias em cada variavel. Para essa tarefa sera utilizada a funcao dummycount()
dummycount(df)
Como podemos observar existem variveis que possuem mais de 150 categorias diferentes. Para fazer a transformação serão utilizadas somente variaveis com menos de 150 categorias.
df.drop(['de_ramo_atividade','de_situacao','nm_fonte_informacao','nm_micro_regiao','de_validade_pgfn','de_validade_fgts','de_optante_simples'],axis=1, inplace=True)
dummycount(df)
Como podemos observar serão geradas 282 novas colunas dummy.
dummy_features = pd.get_dummies(df[df.select_dtypes(include=['object']).columns],dtype=int)
dummy_features.shape
Como podemos observar foram geradas as 282 variaveis dummy.
dummy_features.head(3)
A seguir as varivaveis categoricas sao removidas do dataset para que as variaveis dummy sejam incluidas.
df_teste = df.select_dtypes(exclude=['object'])
df_teste.dtypes
Como podemos observar no dataset so restaram variaveis numericas(int,float). Entretanto, as variaveis cd_ramo_atividade, cd_natureza_juridica representam codigos cujas descrições jÔ foram tratadas na etapa anterior. Portanto essas variaveis serão removidas do dataset.
df_teste.drop(['cd_ramo_atividade','cd_natureza_juridica'],axis=1, inplace=True)
df_teste.head(3)
A seguir as variaveis dummy sao adicionadas ao dataset
df_final = pd.concat([df_teste,dummy_features], axis= 1)
df_final.head(3)
df_final.shape
A seguir a coluna identificadora: id sera separada e armazenada em um dataframe. Como ela não serÔ utilizada no modelo ela podera ser resgatada posteriormente.
df_final_id = df_final['id'].copy()
df_final.drop(['id'],axis=1, inplace=True)
df_final.shape
df_final.shape
A seguir a coluna ind_atividade sera renomada para TARGET para facilitar a separação das outras variaveis.
df_final.rename(columns={'ind_atividade':'TARGET'}, inplace=True)
df_final.dtypes
dataset_train = df_final.copy()
x = dataset_train[dataset_train.columns[~dataset_train.columns.isin(['TARGET'])]]
y = dataset_train[['TARGET']]
normalization = True
scaler = MinMaxScaler()
scaled = pd.DataFrame(scaler.fit_transform(dataset_train))
scaled.columns =dataset_train.columns
x_scaled = scaled[scaled.columns[~scaled.columns.isin(['TARGET'])]]
y_scaled = scaled[['TARGET']]
warnings.filterwarnings('ignore')
#Extracting labels and features for training the model
if (normalization == True):
features = x_scaled
labels = y_scaled
else:
features = x
labels = y
#Extract feature names
feature_names = list(features.columns)
# Convert to np arrays
#features = np.array(features)
#test_features = np.array(test_features)
# Create the kfold object
k=5
k_fold = KFold(n_splits = k, shuffle = True, random_state = 50)
# Empty array for feature importances
feature_importance_values = np.zeros(len(feature_names))
# Empty array for test predictions
#test_predictions = np.zeros(test_features.shape[0])
# Empty array for out of fold validation predictions
out_of_fold = np.zeros(features.shape[0])
out_of_fold_clf = np.zeros(features.shape[0])
out_of_fold_xgb = np.zeros(features.shape[0])
out_of_fold_neural = np.zeros(features.shape[0])
# Lists for recording validation and training scores
valid_scores = []
#train_scores = []
clf_valid_scores = []
#clf_train_scores = []
xgb_valid_scores = []
neural_valid_scores = []
# Iterate through each fold
for train_indices, valid_indices in k_fold.split(features):
# Training data for the fold
train_features, train_labels = features.iloc[train_indices], labels.iloc[train_indices]
# Validation data for the fold
valid_features, valid_labels = features.iloc[valid_indices], labels.iloc[valid_indices]
#Creating the models
lgbm = lgb.LGBMClassifier()
clf = RandomForestClassifier()
rede_neural = MLPClassifier()
xgb = XGBClassifier()
#Training the models
lgbm.fit(train_features,train_labels)
clf.fit(train_features,train_labels)
rede_neural.fit(train_features,train_labels)
xgb.fit(train_features,train_labels)
#Out of fold validation
out_of_fold[valid_indices] = lgbm.predict_proba(valid_features)[:, 1]
out_of_fold_clf[valid_indices] = clf.predict_proba(valid_features)[:, 1]
out_of_fold_neural[valid_indices] = rede_neural.predict_proba(valid_features)[:, 1]
out_of_fold_xgb[valid_indices] = xgb.predict_proba(valid_features)[:, 1]
y_pred_en = lgbm.predict_proba(valid_features)
fpr2, tpr2, thresholds = metrics.roc_curve(valid_labels, y_pred_en[:,1], pos_label=1)
valid_score = metrics.auc(fpr2, tpr2)
y_pred_en = clf.predict_proba(valid_features)
fpr1, tpr1, thresholds = metrics.roc_curve(valid_labels, y_pred_en[:,1], pos_label=1)
clf_valid_score = metrics.auc(fpr1, tpr1)
y_pred_en = rede_neural.predict_proba(valid_features)
fpr, tpr, thresholds = metrics.roc_curve(valid_labels, y_pred_en[:,1], pos_label=1)
rede_neural_valid_score = metrics.auc(fpr, tpr)
y_pred_en = xgb.predict_proba(valid_features)
fpr3, tpr3, thresholds = metrics.roc_curve(valid_labels, y_pred_en[:,1], pos_label=1)
xgb_valid_score = metrics.auc(fpr3, tpr3)
valid_scores.append(valid_score)
#train_scores.append(train_score)
clf_valid_scores.append(clf_valid_score)
#clf_train_scores.append(clf_train_score)
neural_valid_scores.append(rede_neural_valid_score)
xgb_valid_scores.append(xgb_valid_score)
# Clean up memory
gc.enable()
#del lgbm, train_features, valid_features
gc.collect()
# Make the submission dataframe
#submission = pd.DataFrame({'SK_ID_CURR': test_ids, 'TARGET': test_predictions})
# Overall validation score
valid_auc = roc_auc_score(labels, out_of_fold)
valid_auc_clf = roc_auc_score(labels, out_of_fold_clf)
valid_auc_neural = roc_auc_score(labels, out_of_fold_neural)
valid_auc_xgb = roc_auc_score(labels, out_of_fold_xgb)
# Add the overall scores to the metrics
valid_scores.append(valid_auc)
#train_scores.append(np.mean(train_scores))
clf_valid_scores.append(valid_auc_clf)
#clf_train_scores.append(np.mean(clf_train_scores))
neural_valid_scores.append(valid_auc_neural)
xgb_valid_scores.append(valid_auc_xgb)
# Needed for creating dataframe of validation scores
fold_names = list(range(k))
fold_names.append('overall')
# Dataframe of validation scores
metrics2 = pd.DataFrame({'fold': fold_names,
'valid_lightgm': valid_scores,
'valid_xgb': xgb_valid_scores,
'valid_neural': neural_valid_scores,
'valid_randomf': clf_valid_scores})
#return submission, feature_importances, metrics
final = list(metrics2.iloc[k][1:5].values)
#importance = lgbm.feature_importances_
if(final.index(max(final))==0):
importance = lgbm.feature_importances_
best_model = 'lightgm'
else:
if(final.index(max(final))==1):
importance = lgbm.feature_importances_
best_model = 'neural_net'
else:
if(final.index(max(final))==2):
importance = clf.feature_importances_
best_model = 'randomf'
else:
if(final.index(max(final))==3):
importance = xgb.feature_importances_
best_model = 'xgboost'
importancia = pd.DataFrame(
{'variaveis': features.columns,
'peso': importance
})
configure_plotly_browser_state()
init_notebook_mode(connected=False)
import colorlover as cl
color_fold = '#a1c3d1'
#metrics2.drop(columns='fold', inplace = True)
lista = metrics2.columns.values.tolist()
lista = ['metrics2.' + s for s in lista]
lista1 = '[{}]'.format(', '.join(lista))
aux = metrics2.drop(columns='fold')
aux = round(aux,1)*10
aux = aux.astype(int)
lista2 = aux.columns.values.tolist()
lista2 = ['aux.' + s for s in lista2]
lista2 = ['np.array(colors)[' + s + ']' for s in lista2]
lista2.insert(0, 'color_fold')
lista2 = '[{}]'.format(', '.join(lista2))
colors = cl.scales['11']['div']['Spectral']
data = {'Color' : colors}
df = pd.DataFrame(data)
trace0 = go.Table(
header = dict(
values = metrics2.columns.values,
line = dict(color = 'black'),
fill = dict(color = '#a1c3d1'),
align = ['center'],
font = dict(color = 'black', size = 12)
),
cells = dict(
values = eval(lista1),
line = dict(color = 'black'),
fill = dict(color = eval(lista2)),
align = 'center',
font = dict(color = 'black', size = 11)
))
layout1 = dict(
title='The best model was: '+best_model,
)
#data = [trace0]
#fig1 = dict(data=[table_trace1, trace1, trace2, trace3], layout=layout1)
fig1 = dict(data = [trace0], layout=layout1)
iplot(fig1, filename = "row variable color")
configure_plotly_browser_state()
init_notebook_mode(connected=False)
lw = 2
trace0 = go.Scatter(x=fpr3, y=tpr3,
mode='lines',
line=dict(color='red', width=lw),
name='ROC curve: XGBOOST (area = %0.2f)' % round(metrics.auc(fpr3, tpr3),2)
)
trace1 = go.Scatter(x=fpr, y=tpr,
mode='lines',
line=dict(color='navy', width=lw),
name='ROC curve: Neural Net (area = %0.2f)' % round(metrics.auc(fpr, tpr),2)
)
trace2 = go.Scatter(x=fpr1, y=tpr1,
mode='lines',
line=dict(color='darkorange', width=lw),
name='ROC curve: Random Forest (area = %0.2f)' % round(metrics.auc(fpr1, tpr1),2)
)
trace3 = go.Scatter(x=[0, 1], y=[0, 1],
mode='lines',
line=dict(color='black', width=lw, dash='dash'),
name='ROC curve: Baseline (area = 0.5)')
trace4 = go.Scatter(x=fpr2, y=tpr2,
mode='lines',
line=dict(color='green', width=lw),
name='ROC curve: LIghtGBM (area = %0.2f)' % round(metrics.auc(fpr2, tpr2),2)
)
layout = go.Layout(title='Models Performance Benchmark: ROC',
xaxis=dict(title='False Positive Rate'),
yaxis=dict(title='True Positive Rate'))
fig = go.Figure(data=[trace0, trace1, trace2, trace3, trace4], layout=layout)
iplot(fig)
configure_plotly_browser_state()
init_notebook_mode(connected=False)
importancia = importancia.sort_values(by=['peso'], ascending=True)
importancia = importancia[importancia['peso']>30]
data = [go.Bar(
x=importancia['peso'] ,
y=importancia['variaveis'],
orientation = 'h',
)]
layout = go.Layout(title= 'Feature Importance: '+best_model,
autosize=False,
width=900,
height=500,
margin=go.Margin(
l=300
)
)
fig = go.Figure(data=data, layout=layout)
iplot(fig)
Salvando o melhor algoritmo treinado
lgbm.booster_.save_model('/content/drive/MyDrive/CALPM_DATASET/lgb_classifier.txt')
Escrevendo a lista de features utilizada no modelo
features = pd.DataFrame(columns = valid_features.columns)
features.to_csv('/content/drive/MyDrive/CALPM_DATASET/features.csv',index=False, sep=';')
Lendo o algoritmo treinado
lgbm_valid = lgb.Booster(model_file='/content/drive/MyDrive/CALPM_DATASET/lgb_classifier.txt')
Selecionando as colunas necessarias
df = test[['fl_optante_simples',
'fl_matriz',
'fl_spa',
'fl_antt',
'fl_veiculo',
'fl_validade_pgfn',
'fl_validade_fgts',
'vl_total_veiculos_pesados_grupo',
'vl_total_veiculos_leves_grupo',
'fl_optante_simei',
'fl_indicador_financeiro',
'vl_potenc_cons_diesel_grupo',
'vl_potenc_cons_gasolina_grupo',
'fl_simples_irregular',
'vl_total_veiculos_grupo',
'fl_passivel_iss',
'renda_censitaria_2010',
'fl_empresa_contato_contador',
'dt_abertura',
'dh_processamento',
'de_natureza_juridica',
'sg_uf',
'de_classif_natureza_juridica',
'nm_segmento',
'sg_uf_matriz',
'de_precisao_geolocalizacao',
'de_fl_optante_simples',
'de_fl_optante_simei',
'de_fl_simples_irregular',
'nm_meso_regiao',
'id']].copy()
Removendo os missings
df.replace('',np.nan, inplace=True)
remove_missing(df, 0,0)
Convertendo os tipos de variaveis
df.update(df.filter(regex='^fl_').astype(int))
Criandos as mesmas features do treino
df['ano_abertura']=df['dt_abertura'].str.split('-').str[0]
df['ano_processamento']=df['dh_processamento'].str.split('-').str[0]
df['tempo_empresa']= df['ano_processamento'].astype(int) - df['ano_abertura'].astype(int)
df.drop(['ano_abertura','ano_processamento'],axis=1, inplace=True)
dummy_features = pd.get_dummies(df[['de_natureza_juridica',
'sg_uf',
'de_classif_natureza_juridica',
'nm_segmento',
'sg_uf_matriz',
'de_precisao_geolocalizacao',
'de_fl_optante_simples',
'de_fl_optante_simei',
'de_fl_simples_irregular',
'nm_meso_regiao']],dtype=int)
Gerando o dataset final para validacao
df_teste = df.select_dtypes(exclude=['object'])
df_final = pd.concat([df_teste,dummy_features], axis= 1)
df_final.shape
df_final_id = df_final['id'].copy()
df_final.drop(['id'],axis=1, inplace=True)
aligned_features= pd.read_csv('/content/drive/MyDrive/CALPM_DATASET/valid_features.csv',sep=';').columns
df_final_validacao = df_final.reindex(columns = list(aligned_features), fill_value=0)
df_final_validacao.shape
Aplicando o modelo treinado
scaled = pd.DataFrame(scaler.fit_transform(df_final_validacao))
scaled.columns = df_final_validacao.columns
x_scaled = scaled[scaled.columns[~scaled.columns.isin(['TARGET'])]]
valid_features = x_scaled
y_pred_en = lgbm.predict_proba(valid_features)
scaled = pd.DataFrame(scaler.fit_transform(df_final_validacao))
scaled.columns = df_final_validacao.columns
x_scaled = scaled[scaled.columns[~scaled.columns.isin(['TARGET'])]]
valid_features = x_scaled
y_pred_en = lgbm.predict_proba(valid_features)
Escrevendo o resultado da classificação no dataframe
dataset_result = pd.DataFrame({'id':df_final_id,
'y_predito':0,
'y_probabilidade':y_pred_en[:,1].round(2)})
dataset_result.loc[dataset_result['y_probabilidade']>0.5,'y_predito']=1
dataset_result.to_csv('/content/drive/MyDrive/CALPM_DATASET/predicted_dataset.csv',index=False, sep=';')